package com.etonedu.meals.service;

import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;

import androidx.annotation.Nullable;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.ToastUtils;
import com.etonedu.meals.bean.MachineTimeBean;
import com.etonedu.meals.enumeration.MessageEnum;
import com.etonedu.meals.http.LogReportUtils;
import com.etonedu.meals.utils.Utils;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

import android_serialport_api.SerialPort;

public class OffOpenService extends Service {

    private SerialPort mSerialPort;
    private OutputStream mOutputStream;
    private InputStream mInputStream;
    private ReadThread mReadThread;

    private boolean mFlag;
    private Timer timer;
    private Long onTimes;
    private Long openTime;
    private Long offTimes;
    //设置自动开机时间后要关闭读串口的线程
    Handler myHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.arg1) {
                case 1:
                    if (mReadThread != null)
                        mReadThread.interrupt();
                    if (onTimes != null) {
                        String onTimeStr = Utils.timestamp2String1(onTimes, "yyyy-MM-dd HH:mm");
                        ToastUtils.showLong("系统将在 " + onTimes + " 秒开机");
                        LogUtils.e("系统将在" + onTimes + "秒后自动开机!");
                    }
                    break;
            }
            super.handleMessage(msg);
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        EventBus.getDefault().register(this);

        //串口读写数据流
        try {
            mSerialPort = getSerialPort();
            mOutputStream = mSerialPort.getOutputStream();
            mInputStream = mSerialPort.getInputStream();
            mFlag = true;
            LogUtils.e("-----------------mReadThread.start");
        } catch (SecurityException e) {
            LogUtils.e("-----------------SecurityException");
        } catch (IOException e) {
            LogUtils.e("-----------------IOException");
        } catch (InvalidParameterException e) {
            LogUtils.e("-----------------InvalidParameterException");
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        closeSerialPort();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        MachineTimeBean om = intent.getParcelableExtra("time");
        if (om != null) {
            openTime = om.getOnTime();
            offTimes = om.getOffTime();

            LogUtils.e("关机时间:"+om.getOffDate()+",开机时间:"+om.getOnDate());

            String time1 = Utils.timestamp2String1(System.currentTimeMillis(),"yyyy-MM-dd HH:mm:ss");
            String pagek = "com.etonedu.general.edu.machine";
            LogReportUtils.log("设置开关机时间:"+"关机机时间:"+om.getOffDate()+",开机时间:"+om.getOnDate(),pagek,Utils.getLineInfo(),time1);

            long currTime = System.currentTimeMillis();
            String strTime = Utils.timestamp2String1(currTime,"yyyyMMddHHmm");
            long time = Utils.stringToLong(strTime,"yyyyMMddHHmm");

            long min = (openTime - time)/1000;

            onTimes = min;

            mFlag = true;
            writeOnTimeToMC(1,onTimes);
        } else {
            clear();
        }
        return START_STICKY_COMPATIBILITY;
    }

    class WriteTask extends TimerTask {
        public void run() {

            if (onTimes != null) {
                writeOnTimeToMC(1, onTimes);
            }
        }
    }

    @Subscribe
    public void onEvent(String msg) {
        if ("心跳".equals(msg)) {
            long currTime = System.currentTimeMillis();
            String strTime = Utils.timestamp2String1(currTime,"yyyyMMddHHmm");
            long time = Utils.stringToLong(strTime,"yyyyMMddHHmm");

            if (offTimes != null) {
                String str = Utils.timestamp2String1(offTimes,"yyyy-MM-dd HH:ss");
                LogUtils.e("time = "+time+",关机时间 = "+str);
                LogUtils.e("time = "+time+",offTimes = "+offTimes.longValue());
                if (offTimes.longValue() == time) {
                    ToastUtils.showLong("正在关机...");
                    LogUtils.e("正在关机...");

                    long min = (openTime - time)/1000;

                    onTimes = min;

                    mFlag = true;
                    writeOnTimeToMC(1,onTimes);

                    Intent i = new Intent("wits.com.simahuan.shutdown");
                    sendBroadcast(i);

                }
            }
        }
    }

    @Subscribe
    public void refresh(MessageEnum messageEnum) {
        String type = messageEnum.getType();
        if (MessageEnum.ECB_2017.getType().equals(type)) {
            close();
        }
    }

    //读取串口返回数据
    private class ReadThread extends Thread {
        @Override
        public void run() {
            super.run();
            while (mFlag) {
                int size;
                try {

                    byte[] buffer = new byte[1];
                    if (mInputStream == null) {
                        break;
                    }
                    size = mInputStream.read(buffer);

                    if (size > 0) {
                        for (int i = 0; i < size; i++) {
                            //如果串口干扰返回错误数据,重新向单片机写入开机时间.
                            if (buffer[i] != 0x55) {
                                if (timer == null) {
                                    timer = new Timer();
                                    timer.schedule(new WriteTask(), 2000, 1000);
                                }
                                LogUtils.e(
                                        "Data error app will resent data==============="
                                                + +buffer[i]);
                                //串口返回0X55,说明单片机已经接收到正确开机数据.
                            } else if (buffer[i] == 0x55) {
                                LogUtils.e(
                                        " Set boot time ok!"
                                                + buffer[i]);
                                size = 0;
                                mFlag = false;
                                if (timer != null) {
                                    timer.cancel();
                                    timer = null;
                                    LogUtils.e(
                                            "timer cancel!");
                                }
                                Message msg = new Message();
                                msg.arg1 = 1;
                                myHandler.sendMessage(msg);

                            }
                        }
                        // flush_buffer
                        Arrays.fill(buffer, (byte) 0);
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    return;
                }
            }
        }
    }

    //打开串口
    private SerialPort getSerialPort() throws SecurityException, IOException,
            InvalidParameterException {
        // M0,M1,M2默认串口号为ttyS7,M3串口号是ttyS5
        mSerialPort = new SerialPort(new File("/dev/ttyS2"), 9600, 0);
        return mSerialPort;
    }
    //关闭串口
    private void closeSerialPort() {
        LogUtils.e("closeSerialPort");
        if (mSerialPort != null) {
            mSerialPort.close();
            mSerialPort = null;
        }
    }

    /**
     * 设置或取消自动开机时间
     * @param flags
     *            1 为开启自动开机,0为关闭
     * @param times
     *            开机倒计时(单位秒) ,如果要取消自动开机,请将flags,times都设为0
     */
    private void writeOnTimeToMC(int flags, long times) {

        try {
            byte[] mBuffer = longToByteArray(flags, times);
            LogUtils.e("writeOnTimeToMC--------time=" + times);
            long min = times/(60 * 1000);
            LogUtils.e("开机倒计时:"+times);
            int i;
            for (i = 0; i < mBuffer.length; i++)
                LogUtils.e("BUFFER-----HASHCODE=" + mBuffer[i]);
            mReadThread = new ReadThread();
            mReadThread.start();

            if (mOutputStream != null) {
                mOutputStream.write(mBuffer);
                LogUtils.e( "send data 9 byte to serialport.ok");
            } else {
                LogUtils.e("mOutputStream:--------null");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //向单片机发送的数据9个byte
    private byte[] longToByteArray(int flags, long times) {
        byte[] result = new byte[9];
        result[0] = (byte) 0x00;
        result[1] = (byte) 0xaa;
        result[2] = (byte) 0xff;
        result[3] = (byte) 0x55;

        result[4] = (byte) (flags);

        result[5] = (byte) ((times >> 16) & 0xFF);
        result[6] = (byte) ((times >> 8) & 0xFF);
        result[7] = (byte) (times & 0xFF);

        result[8] = (byte) 0x55;

        return result;
    }

    private void close() {
        Intent intentSetOff = new Intent();
        intentSetOff.setAction("wits.com.simahuan.shutdown");
        sendBroadcast(intentSetOff);
    }

    private void clear() {
        writeOnTimeToMC(0,0);
    }
}
